package com.yeskery.nut.util.executor;

import com.yeskery.nut.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 任务步骤实现类
 * @param <T> 执行器数据类型
 * @author sunjay
 * 2024/9/1
 */
public class JobStepImpl<T> implements JobStep<T> {

    /** 名称 */
    private final String name;

    /** 任务步骤执行接口 */
    private final JobStepExecutor<T> jobStepExecutor;

    /** 重试值 */
    private int retryValue;

    /** 执行开始前的等待时间 */
    private long waitTime;

    /** 是否在失败时退出任务 */
    private boolean exitOnFailure;

    /** 是否在错误时退出任务 */
    private boolean exitOnError;

    /**
     * 构建任务步骤实现类
     * @param name name
     * @param jobStepExecutor 任务步骤执行接口
     */
    public JobStepImpl(String name, JobStepExecutor<T> jobStepExecutor) {
        if (StringUtils.isEmpty(name)) {
            throw new ExecuteException("JobStep Name Cannot Be Empty.");
        }
        this.name = name;
        if (jobStepExecutor == null) {
            throw new ExecuteException("JobStep Executor Cannot Be Null.");
        }
        this.jobStepExecutor = jobStepExecutor;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setRetryValue(int retryValue) {
        this.retryValue = retryValue;
    }

    @Override
    public void setWaitTime(long waitTime) {
        this.waitTime = waitTime;
    }

    @Override
    public int retry() {
        return retryValue;
    }

    @Override
    public boolean exitOnFailure() {
        return exitOnFailure;
    }

    @Override
    public void setExitOnFailure(boolean exitOnFailure) {
        this.exitOnFailure = exitOnFailure;
    }

    @Override
    public boolean exitOnError() {
        return exitOnError;
    }

    @Override
    public void setExitOnError(boolean exitOnError) {
        this.exitOnError = exitOnError;
    }

    @Override
    public RunResult execute(T data, ExecutorJobConfigure executorJobConfigure) {
        if (waitTime > 0) {
            try {
                TimeUnit.MILLISECONDS.sleep(waitTime);
            } catch (InterruptedException e) {
                throw new ExecuteException("JobStep[name=" + getName() + "] Execute Interrupted.", e);
            }
        }
        return jobStepExecutor.execute(data, executorJobConfigure);
    }
}
